package com.example.websocketclusterspringbootstarter.aware;

import com.example.websocketclusterspringbootstarter.annotation.EventClassName;
import com.example.websocketclusterspringbootstarter.annotation.EventHandlerName;
import com.example.websocketclusterspringbootstarter.event.BaseEvent;
import com.example.websocketclusterspringbootstarter.handler.EventHandler;
import com.example.websocketclusterspringbootstarter.utils.EventClassUtil;
import com.example.websocketclusterspringbootstarter.utils.EventHandlerUtil;
import org.springframework.beans.BeansException;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.beans.Introspector;
import java.util.Collection;

/**
 * 公共依赖初始化
 *
 * @author zhucc
 * @date 2022-03-08
 */
@Component
public class CommonInitAware implements CommandLineRunner, ApplicationContextAware {

    private volatile ApplicationContext applicationContext;

    private final static String EVENT_NAME_SUFFIX = "Event";

    private final static String EMPTY_STRING = "";


    @Override
    public void run(String... strings) {
        initHandler();
        initEventEntity();
    }

    public void initHandler() {
        Collection<EventHandler> values = this.applicationContext.getBeansOfType(EventHandler.class).values();
        for (EventHandler eventHandler : values) {
            EventHandlerUtil.addHandler(eventHandler.getClass().getAnnotation(EventHandlerName.class).value(), eventHandler);
        }
    }

    public void initEventEntity() {
        Collection<BaseEvent> values = this.applicationContext.getBeansOfType(BaseEvent.class).values();
        for (BaseEvent event : values) {
            EventClassName annotation = event.getClass().getAnnotation(EventClassName.class);
            //没有注解，或者注解上面的值是空（""）
            if (null == annotation || StringUtils.isEmpty(annotation.value())) {
                String simpleName = event.getClass().getSimpleName();
                if (simpleName.contains(EVENT_NAME_SUFFIX)) {
                    simpleName = simpleName.replace(EVENT_NAME_SUFFIX, EMPTY_STRING);
                }
                EventClassUtil.addEventClass(Introspector.decapitalize(simpleName), event.getClass());
            } else {
                EventClassUtil.addEventClass(annotation.value(), event.getClass());
            }
        }
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}